package games.car;

import java.util.*;

public class Level {

    private List<games.car.Car> bootCars = Collections.synchronizedList(new ArrayList<>());
    private List<games.car.Prop> props = Collections.synchronizedList(new ArrayList<>());
    long runId = 0;
    int speed_level = 0;
    int car_speed = games.car.Config.CAR_DEFAULT_SPEED;

    public void load(){
        runId = System.currentTimeMillis();
        new Thread(new CreateCarThread()).start();
        new Thread(new CreatePropThread()).start();
    }

    public void clear(){
        this.runId = System.currentTimeMillis();
        bootCars.clear();
        props.clear();
        speed_level = 0;
        car_speed = games.car.Config.CAR_DEFAULT_SPEED;
    }

    public List<games.car.Car> getBootCar(){
        return bootCars;
    }

    public List<games.car.Prop> getProps(){
        return props;
    }

    public void levelUp(){
        if(speed_level < games.car.Config.LEVEL_SPEED.length){
            speed_level++;
            if(speed_level >= 1 && games.car.Config.LEVEL_SPEED[speed_level - 1].equals(games.car.Config.LEVEL_SPEED[speed_level])){
                car_speed++;
            }
        }
    }

    class CreatePropThread implements Runnable{

        @Override
        public void run() {
            int coverPer = games.car.Config.PROP_COVER_PER;
            int firePer = coverPer + games.car.Config.PROP_FIRE_PER;
            int speedPer = firePer + games.car.Config.PROP_SPEED_PER;

            int max = (games.car.Config.WINDOW_WIDTH - games.car.Config.CAR_WIDTH) / games.car.Config.CAR_WIDTH;
            long tempRunId = runId;
            while(tempRunId == runId){
                if(games.car.Config.state == games.car.Config.State.PAUSE){
                    try {
                        Thread.sleep(300);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if(props.size() > 1){
                        props.remove(props.size()-1);
                    }
                    continue;
                }
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                int x = new Random().nextInt(max) * games.car.Config.CAR_WIDTH + 6;
                games.car.Prop.Type type = games.car.Prop.Type.GOLD;

                int typeNum = new Random().nextInt(100);
                if(typeNum <= coverPer){
                    type = games.car.Prop.Type.COVER;
                }else if(typeNum > coverPer && typeNum <= firePer){
                    type = games.car.Prop.Type.FIRE;
                }else if(typeNum > firePer && typeNum <= speedPer){
                    type = games.car.Prop.Type.SPEED;
                }

                props.add(new games.car.Prop(x,0, type));
            }
        }
    }

    class CreateCarThread implements Runnable{

        @Override
        public void run() {
            int old = 0;
            int max = (games.car.Config.WINDOW_WIDTH - games.car.Config.CAR_WIDTH) / games.car.Config.CAR_WIDTH;
            int[] moreCheck = new int[max];
            int i = 0;
            int seriesCheck = (int)(max * 0.75);
            int left = seriesCheck;
            int right = seriesCheck;
            long tempRunId = runId;
            while(tempRunId == runId){
                if(games.car.Config.state == games.car.Config.State.PAUSE){
                    try {
                        Thread.sleep(300);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    continue;
                }
                int x = new Random().nextInt(max);
                if(x == old){
                    continue;
                }
                if((x - old) == -1){
                    left--;
                }else{
                    left = seriesCheck;
                }
                if((x - old) == 1){
                    right--;
                }else{
                    right = seriesCheck;
                }
                for (int j = 0; j < moreCheck.length; j++) {
                    if(j == x){
                        moreCheck[j] = 0;
                    }else{
                        if(moreCheck[j] < 10){
                            moreCheck[j]++;
                        }else{
                            x = j ;
                            moreCheck[j] = 0;
                        }
                    }
                }
                old = x;
                x = x  * games.car.Config.CAR_WIDTH + 5;
                bootCars.add(new games.car.Car(x ,0,car_speed));
                i++;
                if(i == 100){
                    levelUp();
                }else if(i == 200){
                    levelUp();
                }else if(i == 300){
                    levelUp();
                }
                Iterator<games.car.Car> iterator = bootCars.iterator();
                while(iterator.hasNext()){
                    games.car.Car boot = iterator.next();
                    if(!boot.isLive()){
                        iterator.remove();
                    }
                }
                try {
                    Thread.sleep(Integer.valueOf(games.car.Config.LEVEL_SPEED[speed_level]));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            bootCars.clear();
        }
    }
}
